package com.li.core.service.system.impl;

import com.github.pagehelper.PageHelper;
import com.li.configserve.domain.common.PageParam;
import com.li.configserve.domain.gloabreturn.PageInfoVO;
import com.li.configserve.domain.gloabreturn.ResponseInfo;
import com.li.configserve.domain.gloabreturn.ResultEnum;
import com.li.configserve.utils.redis.RedissonUtils;
import com.li.core.domain.common.CoreRedisConst;
import com.li.core.domain.common.StrConstant;
import com.li.core.domain.system.Menu;
import com.li.core.domain.system.MenuExample;
import com.li.core.domain.system.MenuVO;
import com.li.core.domain.system.User;
import com.li.core.mapper.system.MenuMapper;
import com.li.core.mapper.system.UserMapper;
import com.li.core.service.system.MenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author LiDong
 * @version 1.0.0
 * @createTime 2021年11月21日 17:11:00
 */
@Service
public class MenuServiceImpl implements MenuService {

    @Autowired
    private MenuMapper menuMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private MessageSource messageSource;

    /**
     * 菜单查询接口
     *
     * @param id userid
     * @return
     */
    @Override
    @SuppressWarnings("all")
    public ResponseInfo<List<MenuVO>> listMenuByUserId(String id) {
        String redisKey = CoreRedisConst.MENU + id;
        List<Menu> menus;
        // 管理员
        if (StrConstant.ADMIN_ID.equals(id)) {
            // 先从缓存中获取菜单如果没有则查库
            menus = (List<Menu>) RedissonUtils.getMenuFromRedis(redisKey);
            if (CollectionUtils.isEmpty(menus)) {
                menus = menuMapper.selectByExample(new MenuExample());
                RedissonUtils.addList(redisKey, menus);
            }
            List<MenuVO> menuVOList = packageMenuVo(menus);
            return ResponseInfo.success(StrConstant.SUCCESS, menuVOList);
        }
        // 其它用户
        User user = userMapper.selectByPrimaryKey(Integer.valueOf(id));
        String roleId = user.getRoleId();
        String roleIds;
        if (roleId.contains(StrConstant.COMMA)) {
            roleIds = "'" + String.join("','", Arrays.asList(roleId.split(StrConstant.COMMA))) + "'";
        } else {
            roleIds = "'" + roleId + "'";
        }
        menus = menuMapper.listMenuByRoleIds(roleIds);
        if (CollectionUtils.isEmpty(menus)) {
            menus = (List<Menu>) RedissonUtils.getMenuFromRedis(redisKey);
        }
        List<MenuVO> menuVOList = packageMenuVo(menus);
        RedissonUtils.addList(redisKey, menus);
        return ResponseInfo.success(StrConstant.SUCCESS, menuVOList);
    }

    /**
     * 保存或者修改菜单
     *
     * @param menu
     * @return
     */
    @Override
    public ResponseInfo<Menu> saveOrEditMenu(Menu menu) {
        Integer id = menu.getId();
        if (StringUtils.isEmpty(id)) {
            // 新增
            menuMapper.insert(menu);
            return ResponseInfo.success(ResultEnum.SUCCESS.getCode(), "保存成功！", menu);
        }
        // 修改
        menuMapper.updateByPrimaryKey(menu);
        return ResponseInfo.success(ResultEnum.SUCCESS.getCode(), "修改成功！", menu);
    }

    /**
     * 分页查询菜单
     *
     * @param pageParam
     * @return
     */
    @Override
    public PageInfoVO<MenuVO> listPageMenuVo(PageParam pageParam) {
        PageInfoVO<MenuVO> pageInfoVO = new PageInfoVO<>();
        try {
            Map<String, String> map = pageParam.getParmaMap();
            String id = String.valueOf(map.get("userid"));
            List<Menu> menus;
            // 管理员
            if (StrConstant.ADMIN_ID.equals(id)) {
                PageHelper.startPage(pageParam.getPageNumber(), pageParam.getPageSize());
                menus = menuMapper.selectByExample(new MenuExample());
                List<MenuVO> menuVOList = packageMenuVo(menus);
                pageInfoVO.setCode(ResultEnum.SUCCESS.getCode());
                pageInfoVO.setData(menuVOList);
                return pageInfoVO;
            }
            // 其它用户
            User user = userMapper.selectByPrimaryKey(Integer.valueOf(id));
            String roleId = user.getRoleId();
            String roleIds;
            if (roleId.contains(StrConstant.COMMA)) {
                roleIds = "'" + String.join("','", Arrays.asList(roleId.split(StrConstant.COMMA))) + "'";
            } else {
                roleIds = "'" + roleId + "'";
            }
            PageHelper.startPage(pageInfoVO.getPageNumber(), pageInfoVO.getPageSize());
            menus = menuMapper.listMenuByRoleIds(roleIds);
            List<MenuVO> menuVOList = packageMenuVo(menus);
            pageInfoVO.setCode(ResultEnum.SUCCESS.getCode());
            pageInfoVO.setData(menuVOList);
            return pageInfoVO;
        } catch (Exception e) {
            pageInfoVO.setMessage(messageSource.getMessage("core.pageListError", null, LocaleContextHolder.getLocale()) + e.getMessage());
        }
        return pageInfoVO;
    }


    /**
     * 组装菜单 VO
     *
     * @param menus 菜单
     * @return
     */
    private List<MenuVO> packageMenuVo(List<Menu> menus) {
        List<MenuVO> list = new ArrayList<>();
        if (CollectionUtils.isEmpty(menus)) {
            return list;
        }
        List<Menu> root = menus.stream().filter(x -> StrConstant.ROOT_ID.equals(x.getParentid())).collect(Collectors.toList());
        List<Menu> children = menus.stream().filter(x -> !StrConstant.ROOT_ID.equals(x.getParentid())).collect(Collectors.toList());
        for (Menu menu : root) {
            MenuVO menuVO = new MenuVO();
            menuVO.setId(String.valueOf(menu.getId()));
            menuVO.setTitle(menu.getMenuName());
            menuVO.setIcon(menu.getMenuIcon());
            menuVO.setUrl(menu.getMenuUrl());
            menuVO.setRecordTime(menu.getRecorderTime());
            menuVO.setParentId(menu.getParentid());
            List<MenuVO> rootChildren = new ArrayList<>();
            menuVO.setChildren(rootChildren);
            getMenuChildren(menu, children, rootChildren);
            list.add(menuVO);
        }
        return list;
    }

    /**
     * 递归组装菜单 children
     *
     * @param menu
     * @param children
     * @param rootChildren
     */
    private void getMenuChildren(Menu menu, List<Menu> children, List<MenuVO> rootChildren) {
        for (Menu child : children) {
            if (child.getParentid().equals(String.valueOf(menu.getId()))) {
                MenuVO menuVO = new MenuVO();
                menuVO.setId(String.valueOf(child.getId()));
                menuVO.setTitle(child.getMenuName());
                menuVO.setIcon(child.getMenuIcon());
                menuVO.setUrl(child.getMenuUrl());
                menuVO.setRecordTime(menu.getRecorderTime());
                menuVO.setParentId(child.getParentid());
                rootChildren.add(menuVO);
                List<MenuVO> tempList = new ArrayList<>();
                menuVO.setChildren(tempList);
                getMenuChildren(child, children, tempList);
            }
        }
    }
}
